{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Predições Privadas com Keras Syft"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Passo 3: Predições Privadas usando Syft Keras - Instanciando um cliente"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Parabéns! Após treinar o seu modelo com Keras usual e assegurá-lo com Syft Keras, você está pronto para solicitar algumas previsões privadas."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras.datasets import mnist\n",
    "\n",
    "import syft as sy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Dados"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Aqui, pré-processaremos nossos dados do MNIST. De forma idêntica a como pré-processamos durante o treinamento."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# dimensoes da imagem de entrada\n",
    "img_rows, img_cols = 28, 28\n",
    "\n",
    "# os dados, divididos em conjuntos de treino e teste\n",
    "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n",
    "\n",
    "x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)\n",
    "x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)\n",
    "input_shape = (img_rows, img_cols, 1)\n",
    "\n",
    "x_train = x_train.astype('float32')\n",
    "x_test = x_test.astype('float32')\n",
    "x_train /= 255\n",
    "x_test /= 255"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Conectar ao modelo"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Antes de consultar o modelo, você deve conectar-se a ele. Para isso, você deve criar um cliente. Em seguida, defina exatamente os três TFEWorkers (`alice`, `bob`, e `carol`) e agrupe-os. Finalmente, chame `connect_to_model`. Isso cria um servidor de enfileiramento TFE no lado do cliente que se conecta ao servidor de enfileiramento configurado por `model.serve()`na **Parte 13b**. A fila será responsável pelo compartilhamento secreto dos dados em texto sem formatação antes de enviar os compartilhamentos em uma solicitação de predição."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "num_classes = 10\n",
    "input_shape = (1, 28, 28, 1)\n",
    "output_shape = (1, num_classes)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tf_encrypted:Starting session on target 'grpc://localhost:4000' using config graph_options {\n",
      "}\n",
      "\n"
     ]
    }
   ],
   "source": [
    "client = sy.TFEWorker()\n",
    "\n",
    "alice = sy.TFEWorker(host='localhost:4000')\n",
    "bob = sy.TFEWorker(host='localhost:4001')\n",
    "carol = sy.TFEWorker(host='localhost:4002')\n",
    "cluster = sy.TFECluster(alice, bob, carol)\n",
    "\n",
    "client.connect_to_model(input_shape, output_shape, cluster)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Modelo de Consulta"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Você está pronto para receber algumas predições privadas! Chamando `query_model`, você irá inserir uma `image`na fila criada acima, compartilhar secretamente os dados localmente, e enviar os compartilhamentos para o modelo servidor na **Parte 13b**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# entradas do usuario\n",
    "num_tests = 3\n",
    "images, expected_labels = x_test[:num_tests], y_test[:num_tests]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The image had label 7 and was correctly classified as 7\n",
      "The image had label 2 and was correctly classified as 2\n",
      "The image had label 1 and was correctly classified as 1\n"
     ]
    }
   ],
   "source": [
    "for image, expected_label in zip(images, expected_labels):\n",
    "\n",
    "    res = client.query_model(image.reshape(1, 28, 28, 1))\n",
    "    predicted_label = np.argmax(res)\n",
    "\n",
    "    print(\"The image had label {} and was {} classified as {}\".format(\n",
    "        expected_label,\n",
    "        \"correctly\" if expected_label == predicted_label else \"wrongly\",\n",
    "        predicted_label))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Isso é ótimo. Você é capaz de classificar essas três imagens corretamente! Mas o que há de especial nessas predições é que você não revela nenhuma informação privada para obter este serviço. O modelo instanciado nunca viu seus dados de entrada ou suas predições, e você nunca fez o download do modelo. Você foi capaz de obter previsões privadas sobre dados com um modelo criptografado!\n",
    "\n",
    "Antes de nos adiantarmos para aplicar isso em nossos próprios aplicativos, vamos voltar rapidamente à **Parte 13b** para limpar nosso modelo servido!\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
